package com.web.accountingEntry.service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.web.accountingEntry.entity.AccountingItem;
import com.web.accountingEntry.entity.AccountingJournal;
import com.web.common.aop.AnnotationAop;
import net.bytebuddy.agent.builder.AgentBuilder;
import org.apache.commons.compress.utils.Lists;
import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.web.accountingEntry.entity.AccountingEntry;
import com.web.accountingEntry.mapper.AccountingEntryMapper;
import com.web.position.entity.Position;
import com.web.transaction.entity.Transaction;

@Service
public class AccountingEntryService {

	private final static Logger logger = LoggerFactory.getLogger(AnnotationAop.class);

	@Autowired
    private AccountingEntryMapper mapper;

	public List<Map<String,String>> getAccountingEntries(){
		return mapper.getAccountingEntries();
	};

	public void addAccountingEntry(AccountingEntry ae) {
		mapper.addAccountingEntry(ae);
	}

	public void genAccountingEntries(List<Position> list) {
		List<AccountingEntry> result =Lists.newArrayList();
		LocalDate cutOffDate = LocalDate.now();
		list.stream().forEach(p -> {
			result.addAll(converToAccountingEntry(p,cutOffDate));
		});
		if(!result.isEmpty()){
			saveAccountingEntries(result);
		}
	}

	private List<AccountingEntry> converToAccountingEntry(Position p,LocalDate cutOffDate) {
		List<AccountingEntry> result =Lists.newArrayList();
		AccountingEntry ae = new AccountingEntry();
		ae.setAccountingItem(AccountingItem.ITEM_3100001000.getItem());
		ae.setAcDate(p.getTradeDate());
		ae.setBankCode(p.getBankCode());
		ae.setDealNo(p.getDealNo());
		ae.setCurrency(p.getCurrency());
		if(Transaction.TX_BUY.equals(p.getBuySellOption())) {
			ae.setCreditAmt(p.getAmount());
			ae.setDebitAmt(BigDecimal.ZERO);
		}
		if(Transaction.TX_SELL.equals(p.getBuySellOption())) {
			ae.setDebitAmt(p.getAmount());
			ae.setCreditAmt(BigDecimal.ZERO);
		}

		if(p.getTradeDate().isBefore(cutOffDate)){
			AccountingEntry cloneAe = ae.clone();
			if(Transaction.TX_BUY.equals(p.getBuySellOption())) {
				cloneAe.updateValue(AccountingItem.ITEM_1100000000.getItem(),p.getAmount(),BigDecimal.ZERO,cutOffDate);
			}
			if(Transaction.TX_SELL.equals(p.getBuySellOption())) {
				cloneAe.updateValue(AccountingItem.ITEM_2200000000.getItem(),BigDecimal.ZERO,p.getAmount(),cutOffDate);
			}
			result.add(cloneAe);
		}
		result.add(ae);
		return result;
	}

	public List<AccountingJournal> searchFromAccountingTransaction(Transaction tr){
		List<AccountingJournal> result = mapper.searchFromAccountingTransaction(tr);
		return result;
	}

	public void saveAccsFromTransaction(List<AccountingJournal> accountingEntries, Transaction tr){
		if(accountingEntries  == null || accountingEntries.isEmpty()){
			logger.info("this data is empty");
			return;
		}
		try {
			accountingEntries.stream().forEach(accounting -> {
				AccountingEntry ae = AccountingJournal.setAccountingEntry(accounting,tr);
				addAccountingEntry(ae);
			});
		}catch (Exception e){
			logger.error("saveAccountingEntrys failed",e);
			return;
		}
	}

	public void saveAccountingEntries(List<AccountingEntry> accountingEntries){
		if(accountingEntries  == null || accountingEntries.isEmpty()){
			logger.info("this data is empty");
			return;
		}
		try {
			accountingEntries.stream().forEach(accounting -> {
				addAccountingEntry(accounting);
			});
		}catch (Exception e){
			logger.error("saveAccountingEntrys failed",e);
			return;
		}
	}



	public List<Map<String,String>> getAccountingEcharts (String accountingItem){
		return mapper.getAccountingEcharts(accountingItem);
	}

	public List<String>  getDistinctItem (){
		return mapper.getItem();
	}
}
